home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
INDENT3.ARJ
/
DOINDENT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-04
|
17KB
|
552 lines
#include "indent_globs.h"
struct parser_state match_state[STACK_SIZE];
struct parser_state state_stack[STACK_SIZE];
extern int dec_ind; /* current indentation for declarations */
extern int di_stack[STACKS]; /* a stack of structure indentation levels */
extern int flushed_nl; /* used when buffering up comments to
* remember that a newline was passed over */
extern int force_nl; /* when true, code must be broken */
extern int hd_type; /* used to store type of stmt for if (...),
* for (...), etc */
extern int scase; /* set to true when we see a case, so we will
* know what to do with the following colon */
extern int sp_sw; /* when true, we are in the expressin of
* if(...), while(...), etc. */
extern int squest; /* when this is positive, we have seen a ?
* without the matching : in a <c>?<s>:<s>
* construct */
extern int type_code; /* the type of token, returned by lexi */
extern int last_else; /* true iff last keyword was an else */
extern int is_procname;
void switch_on(type_code)
int type_code;
{
register int i;
register char *t_ptr; /* used for copying tokens */
/*----------------------------------------------------*\
| do switch on type of token scanned
\*----------------------------------------------------*/
switch (type_code) { /* now, decide what to do with the token */
case form_feed: /* found a form feed in line */
ps.use_ff = true; /* a form feed is treated much like a newline */
dump_line();
ps.want_blank = false;
break;
case newline:
if (ps.last_token != comma || ps.p_l_follow > 0
|| !ps.leave_comma || !break_comma || s_com != e_com) {
dump_line();
ps.want_blank = false;
}
++line_no; /* keep track of input line number */
break;
case lparen: /* got a '(' or '[' */
++ps.p_l_follow; /* count parens to make Healy happy */
if (ps.want_blank && *token != '[' &&
(ps.last_token != ident || proc_calls_space
|| (ps.its_a_keyword && !ps.sizeof_keyword)))
*e_code++ = ' ';
if (ps.in_decl && !ps.block_init)
if (troff && !ps.dumped_decl_indent) {
ps.dumped_decl_indent = 1;
sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
e_code += strlen(e_code);
} else {
while ((e_code - s_code) < dec_ind)
*e_code++ = ' ';
*e_code++ = token[0];
}
else
*e_code++ = token[0];
ps.paren_indents[ps.p_l_follow - 1] = e_code - s_code;
ps.want_blank = false;
if (ps.in_or_st && *token == '(') {
/* this is a kluge to make sure that declarations will be
* aligned right if proc decl has an explicit type on it,
* i.e. "int a(x) {..." */
parse(semicolon); /* I said this was a kluge... */
ps.in_or_st = false; /* turn off flag for structure decl
* or initialization */
}
if (ps.sizeof_keyword)
ps.sizeof_mask |= 1 << ps.p_l_follow;
break;
case rparen: /* got a ')' or ']' */
if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.sizeof_mask) {
ps.last_u_d = true;
ps.cast_mask &= (1 << ps.p_l_follow) - 1;
}
ps.sizeof_mask &= (1 << ps.p_l_follow) - 1;
if (--ps.p_l_follow < 0) {
ps.p_l_follow = 0;
diag(0, "Extra %c", *token);
}
if (e_code == s_code) /* if the paren starts the line */
ps.paren_level = ps.p_l_follow; /* then indent it */
*e_code++ = token[0];
ps.want_blank = true;
if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if
* (...), or some such */
sp_sw = false;
force_nl = true;/* must force newline after if */
ps.last_u_d = true; /* inform lexi that a following
* operator is unary */
ps.in_stmt = false; /* dont use stmt continuation
* indentation */
parse(hd_type); /* let parser worry about if, or whatever */
}
ps.search_brace = btype_2; /* this should insure that constructs
* such as main(){...} and int[]{...}
* have their braces put in the right
* place */
break;
case unary_op: /* this could be any unary operation */
if (ps.want_blank)
*e_code++ = ' ';
if (troff && !ps.dumped_decl_indent && ps.in_decl) {
sprintf(e_code, "\\c\n.Du %dp+\200p \"%s\"\n", dec_ind * 7, token);
ps.dumped_decl_indent = 1;
e_code += strlen(e_code);
} else {
char *res = token;
if (ps.in_decl && !ps.block_init) { /* if this is a unary op
* in a declaration, we
* should indent this
* token */
for (i = 0; token[i]; ++i); /* find length of token */
while ((e_code - s_code) < (dec_ind - i))
*e_code++ = ' '; /* pad it */
}
if (troff && token[0] == '-' && token[1] == '>')
res = "\\(->";
for (t_ptr = res; *t_ptr; ++t_ptr)
*e_code++ = *t_ptr;
}
ps.want_blank = false;
break;
case binary_op: /* any binary operation */
do_binary:
if (ps.want_blank)
*e_code++ = ' ';
{
char *res = token;
if (troff)
switch (token[0]) {
case '<':
if (token[1] == '=')
res = "\\(<=";
break;
case '>':
if (token[1] == '=')
res = "\\(>=";
break;
case '!':
if (token[1] == '=')
res = "\\(!=";
break;
case '|':
if (token[1] == '|')
res = "\\(br\\(br";
else if (token[1] == 0)
res = "\\(br";
break;
case '-':
if (token[1] == '>')
res = "\\(->";
}
for (t_ptr = res; *t_ptr; ++t_ptr)
*e_code++ = *t_ptr; /* move the operator */
}
ps.want_blank = true;
break;
case postop: /* got a trailing ++ or -- */
*e_code++ = token[0];
*e_code++ = token[1];
ps.want_blank = true;
break;
case question: /* got a ? */
squest++; /* this will be used when a later colon
* appears so we can distinguish the
* <c>?<n>:<n> construct */
if (ps.want_blank)
*e_code++ = ' ';
*e_code++ = '?';
ps.want_blank = true;
break;
case casestmt: /* got word 'case' or 'default' */
scase = true; /* so we can process the later colon properly */
goto copy_id;
case colon: /* got a ':' */
if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */
--squest;
if (ps.want_blank)
*e_code++ = ' ';
*e_code++ = ':';
ps.want_blank = true;
break;
}
if (ps.in_decl) {
*e_code++ = ':';
ps.want_blank = false;
break;
}
ps.in_stmt = false; /* seeing a label does not imply we are in a
* stmt */
for (t_ptr = s_code; *t_ptr; ++t_ptr)
*e_lab++ = *t_ptr; /* turn everything so far into a
* label */
e_code = s_code;
*e_lab++ = ':';
*e_lab++ = ' ';
*e_lab = '\0';
force_nl = ps.pcase = scase; /* ps.pcase will be used by
* dump_line to decide how to
* indent the label. force_nl
* will force a case n: to be
* on a line by itself */
scase = false;
ps.want_blank = false;
break;
case semicolon: /* got a ';' */
ps.in_or_st = false;/* we are not in an initialization or
* structure declaration */
scase = false; /* these will only need resetting in a error */
squest = 0;
if (ps.last_token == rparen)
ps.in_parameter_declaration = 0;
ps.cast_mask = 0;
ps.sizeof_mask = 0;
ps.block_init = 0;
ps.just_saw_decl--;
if (ps.in_decl && s_code == e_code && !ps.block_init)
while ((e_code - s_code) < (dec_ind - 1))
*e_code++ = ' ';
ps.in_decl = (ps.dec_nest > 0); /* if we were in a first
* level structure
* declaration, we arent any
* more */
if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {
/* This should be true iff there were unbalanced parens in
* the stmt. It is a bit complicated, because the semicolon
* might be in a for stmt */
diag(1, "Unbalanced parens");
ps.p_l_follow = 0;
if (sp_sw) { /* this is a check for a if, while, etc. with
* unbalanced parens */
sp_sw = false;
parse(hd_type); /* dont lose the if, or whatever */
}
}
*e_code++ = ';';
ps.want_blank = true;
ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the
* middle of a stmt */
if (!sp_sw) { /* if not if for (;;) */
parse(semicolon); /* let parser know about end of stmt */
force_nl = true;/* force newline after a end of stmt */
}
break;
case lbrace: /* got a 'lbrace' */
ps.in_stmt = false; /* dont indent the {} */
if (!ps.block_init)
force_nl = true;/* force other stuff on same line as 'lbrace'
* onto new line */
if (s_code != e_code && !ps.block_init) {
if (!btype_2) {
dump_line();
ps.want_blank = false;
} else if (ps.in_parameter_declaration && !ps.in_or_st) {
ps.i_l_follow = 0;
dump_line();
ps.want_blank = false;
}
}
if (ps.in_parameter_declaration)
prefix_blankline_requested = 0;
if (ps.p_l_follow > 0) { /* check for preceding unbalanced
* parens */
diag(1, "Unbalanced parens");
ps.p_l_follow = 0;
if (sp_sw) { /* check for unclosed if, for, etc. */
sp_sw = false;
parse(hd_type);
ps.ind_level = ps.i_l_follow;
}
}
if (s_code == e_code)
ps.ind_stmt = false; /* dont put extra indentation on line
* with '{' */
if (ps.in_decl && ps.in_or_st) { /* this is either a structure
* declaration or an init */
di_stack[ps.dec_nest++] = dec_ind;
dec_ind = 0;
} else {
ps.decl_on_line = false; /* we cant be in the middle
* of a declaration, so dont
* do special indentation of
* comments */
ps.in_parameter_declaration = 0;
}
parse(lbrace); /* let parser know about this */
if (ps.want_blank) /* put a blank before '{' if '{' is not at
* start of line */
*e_code++ = ' ';
ps.want_blank = false;
*e_code++ = '{';
ps.just_saw_decl = 0;
break;
case rbrace: /* got a '}' */
if (ps.p_l_follow) {/* check for unclosed if, for, else. */
diag(1, "Unbalanced parens");
ps.p_l_follow = 0;
sp_sw = false;
}
ps.just_saw_decl = 0;
if (s_code != e_code && !ps.block_init) { /* '}' must be first on
* line */
if (verbose)
diag(0, "Line broken");
dump_line();
}
*e_code++ = '}';
ps.want_blank = true;
ps.in_stmt = ps.ind_stmt = false;
if (ps.dec_nest > 0) { /* we are in multi-level structure
* declaration */
dec_ind = di_stack[--ps.dec_nest];
if (ps.dec_nest == 0 && !ps.in_parameter_declaration)
ps.just_saw_decl = 2;
ps.in_decl = true;
}
prefix_blankline_requested = 0;
parse(rbrace); /* let parser know about this */
ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead && ps.il[ps.tos] >= ps.ind_level;
if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)
postfix_blankline_requested = 1;
break;
case swstmt: /* got keyword "switch" */
sp_sw = true;
hd_type = swstmt; /* keep this for when we have seen the
* expression */
goto copy_id; /* go move the token into buffer */
case sp_paren: /* token is if, while, for */
sp_sw = true; /* the interesting stuff is done after the
* expression is scanned */
hd_type = (*token == 'i' ? ifstmt :
(*token == 'w' ? whilestmt : forstmt));
/* remember the type of header for later use by parser */
goto copy_id; /* copy the token into line */
case sp_nparen: /* got else, do */
ps.in_stmt = false;
if (*token == 'e') {
if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {
if (verbose)
diag(0, "Line broken");
dump_line();/* make sure this starts a line */
ps.want_blank = false;
}
force_nl = true;/* also, following stuff must go onto new
* line */
last_else = 1;
parse(elselit);
} else {
if (e_code != s_code) { /* make sure this starts a
* line */
if (verbose)
diag(0, "Line broken");
dump_line();
ps.want_blank = false;
}
force_nl = true;/* also, following stuff must go onto new
* line */
last_else = 0;
parse(dolit);
}
goto copy_id; /* move the token into line */
case decl: /* we have a declaration type (int, register,
* etc.) */
parse(decl); /* let parser worry about indentation */
if (ps.last_token == rparen && ps.tos <= 1)
ps.in_parameter_declaration = 1;
if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) {
ps.ind_level = ps.i_l_follow = 1;
ps.ind_stmt = 0;
}
ps.in_or_st = true; /* this might be a structure or
* initialization declaration */
ps.in_decl = ps.decl_on_line = true;
if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)
ps.just_saw_decl = 2;
prefix_blankline_requested = 0;
for (i = 0; token[i++];); /* get length of token */
/* dec_ind = e_code - s_code + (ps.decl_indent>i ? ps.decl_indent
* : i); */
dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;
goto copy_id;
case ident: /* got an identifier or constant */
if (ps.in_decl) { /* if we are in a declaration, we must indent
* identifier */
if (ps.want_blank)
*e_code++ = ' ';
ps.want_blank = false;
if (is_procname == 0 || !procnames_start_line) {
if (!ps.block_init)
if (troff && !ps.dumped_decl_indent) {
sprintf(e_code, "\\c\n.De %dp+\200p\n", dec_ind * 7);
ps.dumped_decl_indent = 1;
e_code += strlen(e_code);
} else
while ((e_code - s_code) < dec_ind)
*e_code++ = ' ';
} else {
if (dec_ind && s_code != e_code)
dump_line();
dec_ind = 0;
ps.want_blank = false;
}
} else if (sp_sw && ps.p_l_follow == 0) {
sp_sw = false;
force_nl = true;
ps.last_u_d = true;
ps.in_stmt = false;
parse(hd_type);
}
copy_id:
if (ps.want_blank)
*e_code++ = ' ';
if (troff && ps.its_a_keyword) {
*e_code++ = BACKSLASH;
*e_code++ = 'f';
*e_code++ = 'B';
}
for (t_ptr = token; *t_ptr; ++t_ptr)
*e_code++ = *t_ptr;
if (troff && ps.its_a_keyword) {
*e_code++ = BACKSLASH;
*e_code++ = 'f';
*e_code++ = 'R';
}
ps.want_blank = true;
break;
case period: /* treat a period kind of like a binary
* operation */
*e_code++ = '.'; /* move the period into line */
ps.want_blank = false; /* dont put a blank after a period */
break;
case comma:
ps.want_blank = (s_code != e_code); /* only put blank after
* comma if comma does
* not start the line */
if (ps.in_decl && is_procname == 0 && !ps.block_init)
while ((e_code - s_code) < (dec_ind - 1))
*e_code++ = ' ';
*e_code++ = ',';
if (ps.p_l_follow == 0) {
ps.block_init = 0;
if (break_comma && !ps.leave_comma)
force_nl = true;
}
break;
case preesc: /* got the character '#' */
if ((s_com != e_com) || (s_lab != e_lab) || (s_code != e_code)) {
dump_line();
}
*e_lab++ = '#'; /* move whole line to 'label' buffer */
/* a large section of code was removed here to break these files
* up into msc sized chunks */
dopreesc();
if (strncmp(s_lab, "#if", 3) == 0) {
if (ifdef_level < sizeof state_stack / sizeof state_stack[0]) {
match_state[ifdef_level].tos = -1;
state_stack[ifdef_level++] = ps;
} else {
diag(1, "#if stack overflow");
}
} else if (strncmp(s_lab, "#else", 5) == 0) {
if (ifdef_level <= 0) {
diag(1, "Unmatched #else");
} else {
match_state[ifdef_level - 1] = ps;
ps = state_stack[ifdef_level - 1];
}
} else if (strncmp(s_lab, "#endif", 6) == 0) {
if (ifdef_level <= 0) {
diag(1, "Unmatched #endif");
} else {
ifdef_level--;
#ifdef undef
/* This match needs to be more intelligent before the
* message is useful */
if (match_state[ifdef_level].tos >= 0
&& /* bcmp */ memcmp(&ps, &match_state[ifdef_level], sizeof ps))
diag(0, "Syntactically inconsistant #ifdef alternatives.");
#endif
}
}
break; /* subsequent processing of the newline
* character will cause the line to be
* printed */
case comment: /* we have gotten a /* this is a biggie */
proc_comment:
if (flushed_nl) { /* we should force a broken line here */
flushed_nl = false;
dump_line();
ps.want_blank = false; /* dont insert blank at line start */
force_nl = false;
}
pr_comment();
break;
} /* end of big switch stmt */
}